package mylibrary.reflect;

import java.lang.reflect.Constructor;
import java.lang.reflect.Field;
import java.lang.reflect.Method;

public class Test {

	public static void main(String[] args) throws Exception {
		
		User user = new User("name", 123, "F");
		System.out.println(getProperty(user, "sex"));
		
		System.out.println(getStaticProperty("reflect.User", "id"));
		
		System.out.println(invokeMethodWithoutArgs(user, "plus"));
		System.out.println(invokeMethodWithArgs(user, "plus", new Object[0]));
		
		System.out.println(invokeStaticMethod("reflect.User", "add", new Object[0]));
		
		Object[] newArgs = {"gaoshuai", 10, "M"};
		User user1 = (User)getNewInstance("reflect.User", newArgs);
		System.out.println(user1 + ":" +user1.getName() + " " + user1.getNumber() + " " + user1.sex);
		System.out.println(Class.forName("reflect.User").newInstance());
		
		User o = new User();
		Field field = o.getClass().getDeclaredField("op");
		field.setAccessible(true);
		field.set(o, "inpatient");
		System.out.println(o.getOp());
		
		Method method = o.getClass().getDeclaredMethod("f1", new Class[0]);
		method.setAccessible(true);
		System.out.println(method.invoke(o, null));
	}
	
	public static Object getProperty(Object owner, String fieldName) throws Exception {
		
		Class ownerClass = owner.getClass();
		Field field = ownerClass.getField(fieldName);
		Object property = field.get(owner);
		return property;
	}
	
	public static Object getStaticProperty(String className, String fieldName) throws Exception {
		
		Class ownerClass = Class.forName(className);
		Field field = ownerClass.getField(fieldName);
		Object property = field.get(ownerClass);
		return property;
	}
	
	public static Object invokeMethodWithArgs(Object owner, String methodName, Object[] args) throws Exception {
		
		Class ownerClass = owner.getClass();
		Class[] argsClass = new Class[args.length];
		
		for(int i=0; i<args.length; i++) {
			argsClass[i] = args[i].getClass();
		}
		
		Method method = ownerClass.getMethod(methodName, argsClass);
		return method.invoke(owner, args);
	}
	
	public static Object invokeMethodWithoutArgs(Object owner, String methodName) throws Exception {
		
		Class ownerClass = owner.getClass();
		Method method = ownerClass.getMethod(methodName, null);
		return method.invoke(owner);
		
	}
	
	public static Object invokeStaticMethod(String className, String methodName, Object[] args) throws Exception {
		
		Class ownerClass = Class.forName(className);
		Class[] argsClass = new Class[args.length];
		
		for(int i=0; i<args.length; i++) {
			argsClass[i] = args[i].getClass();		
		}
		
		Method method = ownerClass.getMethod(methodName, argsClass);
		return method.invoke(null, argsClass);
	}
	
	public static Object getNewInstance(String className, Object[] args) throws Exception {	//基本类型参数的情况被排除了
		
		Class newOneClass = Class.forName(className);
		Class[] argsClass = new Class[args.length];
		
		for(int i=0; i<args.length; i++) {
			argsClass[i] = args[i].getClass();		
		}
		
		Constructor constructor = newOneClass.getConstructor(argsClass);
		return constructor.newInstance(args);
	}
	
	public void f(int a){}
	public void f(Integer a){}
}
